// ptrace.c - ptrace 基础封装
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdint.h>
#include "bp.h"

uint64_t ptrace_read(uintptr_t addr) {
    errno = 0;
    long word = ptrace(PTRACE_PEEKDATA, pid_global, addr, 0);
    if (errno) return -1;
    return (uint64_t)word;
}

int ptrace_write(uintptr_t addr, uint64_t word) {
    if (ptrace(PTRACE_POKEDATA, pid_global, addr, word) < 0) return -1;
    return 0;
}

/* 回滚 PC、单步、重新下断点 */
void ptrace_step_over_bp(bp_t *bp) {
    struct user_regs_struct regs;
    ptrace(PTRACE_GETREGS, pid_global, 0, &regs);
    regs.rip = bp->addr;                 // 1. 回退
    ptrace_write(bp->addr, bp->saved);   // 2. 恢复原指令
    ptrace(PTRACE_SETREGS, pid_global, 0, &regs);
    ptrace(PTRACE_SINGLESTEP, pid_global, 0, 0); // 3. 单步
    int status;
    waitpid(pid_global, &status, 0);
    ptrace_write(bp->addr, (bp->saved & ~0xFF) | 0xCC); // 4. 再下断
}